package com.demo.algorithms.leetcode;

import java.util.*;

/**
 * 力扣练习
 *
 * @author 蔡奇峰
 */
public class Practice {
    public static void main(String[] args) {

        int i = 0, j = 0;
        System.out.printf("i: %d \t  j：%d  \n", i++, ++j);
        System.out.println("i: " + i + "\t  j: " + j);
        int[] nums = {0, -1, -1};

        System.out.println("反转前：-2147483648");
        int reverse = reverse(-2147483648);
        System.out.println("reverse:" + reverse);

//        List<List<Integer>> lists = myThreeSum(nums);
//        System.out.println(lists.toString());

    }

    /**
     * 给你一个包含 n 个整数的数组 nums，判断 nums 中是否存在三个元素 a，b，c ，
     * 使得 a + b + c = 0 ？请你找出所有满足条件且不重复的三元组。
     * <p>
     * 注意：答案中不可以包含重复的三元组。
     *
     * @param nums
     * @return
     */
    public static List<List<Integer>> threeSum(int[] nums) {
        int n = nums.length;
        Arrays.sort(nums);
        List<List<Integer>> ans = new ArrayList<List<Integer>>();
        // 枚举 a
        for (int first = 0; first < n; ++first) {
            // 需要和上一次枚举的数不相同
            if (first > 0 && nums[first] == nums[first - 1]) {
                continue;
            }
            // c 对应的指针初始指向数组的最右端
            int third = n - 1;
            int target = -nums[first];
            // 枚举 b
            for (int second = first + 1; second < n; ++second) {
                // 需要和上一次枚举的数不相同
                if (second > first + 1 && nums[second] == nums[second - 1]) {
                    continue;
                }
                // 需要保证 b 的指针在 c 的指针的左侧
                while (second < third && nums[second] + nums[third] > target) {
                    --third;
                }
                // 如果指针重合，随着 b 后续的增加
                // 就不会有满足 a+b+c=0 并且 b<c 的 c 了，可以退出循环
                if (second == third) {
                    break;
                }
                if (nums[second] + nums[third] == target) {
                    List<Integer> list = new ArrayList<Integer>();
                    list.add(nums[first]);
                    list.add(nums[second]);
                    list.add(nums[third]);
                    ans.add(list);
                }
            }
        }
        return ans;
    }

    /**
     * 给出一个 32 位的有符号整数，你需要将这个整数中每位上的数字进行反转。
     * <p>
     * 假设我们的环境只能存储得下 32 位的有符号整数，则其数值范围为 [−231,  231 − 1]。
     * 请根据这个假设，如果反转后整数溢出那么就返回 0。
     *
     * @param x
     * @return
     */
    public static int reverse(int x) {
        int ans = 0;
        while (x != 0) {
            int pop = x % 10;
            if (ans > Integer.MAX_VALUE / 10 || (ans == Integer.MAX_VALUE / 10 && pop > 7)) {
                return 0;
            }
            if (ans < Integer.MIN_VALUE / 10 || (ans == Integer.MIN_VALUE / 10 && pop < -8)) {
                return 0;
            }
            ans = ans * 10 + pop;
            x /= 10;
        }
        return ans;

       /* String res = "", temp = "";
        boolean flag = false;
        if(x > 0){
            temp = "" + x;
        }else if(x < 0){
            flag = true;
            temp = ("" + x).replace("-", "");
            System.out.println("temp:" + temp);
        }else{
            return 0;
        }

        for(int i = temp.length() - 1; i >= 0; --i){
            String s = temp.charAt(i) + "";
            res += s;
        }
        double reverse = flag ? -(Double.parseDouble(res)) : Double.parseDouble(res);
        if (reverse > Integer.MAX_VALUE || reverse < Integer.MIN_VALUE){
            return 0;
        }

        return (int) reverse;*/
    }


    public static List<List<Integer>> myThreeSum(int[] nums) {
        int len = nums.length;
        Map<String, Integer> map = new HashMap<String, Integer>(len);
        Set<String> set = new HashSet<>();
        Arrays.sort(nums);
        for (int i = 0; i < len; i++) {
            map.put(nums[i] + "", i);
        }
        List<List<Integer>> ans = new ArrayList<List<Integer>>();
        if (nums[0] > 0) {
            return ans;
        }
        int first = 0, last = 0, start = 0, end = len - 1;

        while (start < end) {
            first = nums[start];
            last = nums[end];

            int second = 0 - (last + first);
            if (map.containsKey(second + "")) {
                Integer m = map.get(second + "");
                if (m != start && m != end) {
                    boolean flag = false;
                    List<Integer> list = new ArrayList<Integer>();
                    if (second < first) {
                        flag = set.add("" + second + first + last);

                        if (flag) {
                            list.add(second);
                            list.add(first);
                            list.add(last);
                            ans.add(list);
                        }
                    } else if (second > last) {
                        flag = set.add("" + first + last + second);

                        if (flag) {
                            list.add(first);
                            list.add(last);
                            list.add(second);
                            ans.add(list);
                        }
                    } else if (second >= first && second < last) {
                        flag = set.add("" + first + second + last);

                        if (flag) {
                            list.add(first);
                            list.add(second);
                            list.add(last);
                            ans.add(list);
                        }
                    }


                }
            }
            if ((first + last) > 0) {
                --end;
            } else {
                ++start;
            }

        }
        System.out.println("set:" + set.toString());

        return ans;
    }


}
